package tr.edu.metu.is.mega.client.course.activity;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import tr.edu.metu.is.mega.client.core.AsyncCallbackAdapter;
import tr.edu.metu.is.mega.client.core.MegaUtil;
import tr.edu.metu.is.mega.client.core.event.SelectionEventBus;
import tr.edu.metu.is.mega.client.core.event.SelectionEventListener;
import tr.edu.metu.is.mega.client.course.CourseChangeEvent;
import tr.edu.metu.is.mega.client.resource.MEGAIconBundle;
import tr.edu.metu.is.mega.client.resource.MEGAResourceBundle;
import tr.edu.metu.is.mega.client.resource.MEGAResources;
import tr.edu.metu.is.mega.client.service.GwtSubmissionViewService;
import tr.edu.metu.is.mega.common.dto.ActivityType;
import tr.edu.metu.is.mega.common.dto.CourseDTO;
import tr.edu.metu.is.mega.common.dto.SubmissionViewDTO;
import tr.edu.metu.is.mega.common.dto.TeamDTO;
import tr.edu.metu.is.mega.common.dto.UserRole;

import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FillLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.AbstractImagePrototype;

/**
 * Window for defining and changing activity records.
 */
public class ActivityManagementPanel extends LayoutContainer {

    private MEGAResourceBundle resourceBundle;

    private MEGAIconBundle iconBundle;

    private Grid<BeanModel> grid;

    private BeanModelFactory beanModelFactory;

    private CourseDTO course;

    private TeamDTO team;

    private final UserRole role;

    private ToolBar toolBar;

    private Button uploadSubmissionButton;

    private Button downloadReviewButton;

    /**
     * Default constructor.
     */
    public ActivityManagementPanel(UserRole role) {
        this.role = role;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        setLayout(new FitLayout());
        resourceBundle = MEGAResources.RESOURCEBUNDLE;
        iconBundle = MEGAResources.ICONBUNDLE;
        beanModelFactory = BeanModelLookup.get().getFactory(SubmissionViewDTO.class);

        FieldSet set = new FieldSet();
        if (role == UserRole.STUDENT) {
            set.setHeight(400);
        } else {
            set.setHeight(200);
        }
        set.setLayout(new FillLayout());
        set.setHeading(resourceBundle.activityTemplateHeading());

        ContentPanel panel = new ContentPanel();
        panel.setHeaderVisible(false);

        panel.add(getGrid());
        panel.setTopComponent(getToolBar());

        set.add(panel);
        add(set);
        SelectionEventBus.getInstance().registerListener(CourseChangeEvent.Update.class, new SelectionEventListener<CourseDTO>() {

            @Override
            public void selectionChanged(CourseDTO selectedObject) {
                course = selectedObject;
            }

        });
        SelectionEventBus.getInstance().registerListener(CourseChangeEvent.TeamSelected.class, new SelectionEventListener<TeamDTO>() {

            @Override
            public void selectionChanged(TeamDTO selectedObject) {
                team = selectedObject;
                GwtSubmissionViewService.Util.getInstance().getSubmissions(role, selectedObject.getCourse().getPkid(), selectedObject.getPkid(),
                        new AsyncCallbackAdapter<List<SubmissionViewDTO>>() {

                            @Override
                            public void onSuccess(List<SubmissionViewDTO> result) {
                                setActivities(result);
                            }
                        });
            }
        });
    }

    /**
     * Initializes and returns toolbar.
     * 
     * @return toolbar
     */
    private ToolBar getToolBar() {
        toolBar = new ToolBar();
        toolBar.setMinButtonWidth(70);
        toolBar.setSpacing(5);
        if (role != UserRole.STUDENT) {
            Button assignReviewerButton = new Button(resourceBundle.assignReviewer(), AbstractImagePrototype.create(iconBundle.assignReviewer()));
            assignReviewerButton.addSelectionListener(ActivityManagementHelpers.getAssignReviewerAction(this));
            toolBar.add(assignReviewerButton);
        }

        uploadSubmissionButton = new Button(resourceBundle.uploadSubmission(), AbstractImagePrototype.create(iconBundle.uploadReport()));
        uploadSubmissionButton.addSelectionListener(ActivityManagementHelpers.getUploadSubmissionAction(this));
        toolBar.add(uploadSubmissionButton);

        Button downloadSubmissionButton = new Button(resourceBundle.downloadSubmission(), AbstractImagePrototype.create(iconBundle.download()));
        downloadSubmissionButton.addSelectionListener(ActivityManagementHelpers.getDownloadSubmissionAction(this));
        toolBar.add(downloadSubmissionButton);

        if (role == UserRole.STUDENT) {
            Button showRevisionsButton = new Button("Revisions", AbstractImagePrototype.create(iconBundle.showRevision()));
            showRevisionsButton.addSelectionListener(ActivityManagementHelpers.getShowRevisionsAction(this));
            toolBar.add(showRevisionsButton);
        }

        downloadReviewButton = new Button(resourceBundle.downloadReview(), AbstractImagePrototype.create(iconBundle.downloadReviewReport()));
        downloadReviewButton.addSelectionListener(ActivityManagementHelpers.getDownloadReviewReportAction(this));
        toolBar.add(downloadReviewButton);

        Button exportButton = new Button(resourceBundle.exportToGoogleCalendar(), AbstractImagePrototype.create(iconBundle.exportToGoogleCalendar()));
        exportButton.addSelectionListener(ActivityManagementHelpers.getExportToGoogleCalendarAction(this));
        toolBar.add(exportButton);

        Button downloadAllButton = new Button(resourceBundle.downloadAll(), AbstractImagePrototype.create(iconBundle.downloadAll()));
        downloadAllButton.addSelectionListener(ActivityManagementHelpers.getDownloadAllAction(this));
        toolBar.add(downloadAllButton);

        return toolBar;
    }

    /**
     * Returns activity grid.
     * 
     * @return grid
     */
    public Grid<BeanModel> getGrid() {
        if (grid == null) {

            ListStore<BeanModel> store = new ListStore<BeanModel>();

            List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
            columns.add(new ColumnConfig(SubmissionViewDTO.FIELD_DESC, resourceBundle.activityTemplateDescription(), 50));
            ColumnConfig columnConfig = new ColumnConfig(SubmissionViewDTO.FIELD_DUEDATE, resourceBundle.activityTemplateDueDate(), 50);
            columnConfig.setRenderer(MegaUtil.getDateRenderer(MegaUtil.LONG_DATE_STYLE));
            columns.add(columnConfig);
            columns.add(new ColumnConfig(SubmissionViewDTO.FIELD_REVIEVER, "Reviewer", 50));
            columnConfig = new ColumnConfig(SubmissionViewDTO.FIELD_SUBMISSIONDATE, "Submission Date", 50);
            columnConfig.setRenderer(MegaUtil.getDateRenderer(MegaUtil.LONG_DATE_STYLE));
            columns.add(columnConfig);
            columns.add(new ColumnConfig(SubmissionViewDTO.FIELD_SUBMITTEDBY, "Submitted By", 50));
            columnConfig = new ColumnConfig(SubmissionViewDTO.FIELD_REVIEWDATE, "Review Date", 50);
            columnConfig.setRenderer(MegaUtil.getDateRenderer(MegaUtil.LONG_DATE_STYLE));
            columns.add(columnConfig);
            ColumnModel cm = new ColumnModel(columns);

            grid = new Grid<BeanModel>(store, cm);

            grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<BeanModel>() {

                @Override
                public void selectionChanged(SelectionChangedEvent<BeanModel> se) {
                    if (se.getSelectedItem() != null) {
                        SubmissionViewDTO view = se.getSelectedItem().getBean();
                        if (view.getSubmissiontype() == ActivityType.ACTIVITY) {
                            toolBar.setEnabled(false);
                        } else {
                            toolBar.setEnabled(true);
                            uploadSubmissionButton.setEnabled(true);
                            if (role == UserRole.STUDENT) {
                                if (view.getSubmissiontype() != ActivityType.ACTIVITY && view.getDuedate().before(new Date())) {
                                    uploadSubmissionButton.setEnabled(false);
                                }
                            }
                        }
                    } else {
                        toolBar.setEnabled(true);
                    }
                }
            });

            MegaUtil.decoradeGridViewWithAutoHeight(grid, false);
            if (role == UserRole.STUDENT) {
                grid.setHeight(360);
            } else {
                grid.setHeight(130);
            }

        }
        return grid;
    }

    /**
     * Adds activities to grid
     * 
     * @param activityList
     */
    public void setActivities(List<SubmissionViewDTO> activityList) {
        getGrid().getStore().removeAll();
        for (SubmissionViewDTO activity : activityList) {
            getGrid().getStore().add(beanModelFactory.createModel(activity));
        }
        getGrid().getStore().sort(SubmissionViewDTO.FIELD_DUEDATE, SortDir.ASC);
    }

    /**
     * Returns course.
     * 
     * @return the course
     */
    public CourseDTO getCourse() {
        return course;
    }

    /**
     * Returns team.
     * 
     * @return the team
     */
    public TeamDTO getTeam() {
        return team;
    }

    /**
     * Returns role.
     * 
     * @return the role
     */
    public UserRole getRole() {
        return role;
    }

}
